using System;
using System.Data;
using Microsoft.SqlServer.Server;
using System.Data.SqlTypes;
using System.IO;
using System.Text;


[Serializable]
[SqlUserDefinedAggregate(Format.UserDefined, IsInvariantToNulls = true, IsInvariantToDuplicates = false, IsInvariantToOrder = true, MaxByteSize = -1)]
public class FirstAgg : IBinarySerialize
{
    private StringBuilder recs_buffer;
    private Int64 recs_cnt;

    // Initialize the internal data structures
    public void Init()
    {
        this.recs_buffer = new StringBuilder();
        this.recs_cnt = 0; 
    }

    // Accumulate the next value, not if the value is null
    public void Accumulate(SqlString rec_value)
    {
        this.recs_cnt = this.recs_cnt + 1;

        if (rec_value.IsNull)
        {
            return;
        }

        if (recs_cnt == 1)
        {
            this.recs_buffer.Append(rec_value.Value);
            return;
        }
    }

    // Merge the partially computed aggregate with this aggregate.
    public void Merge(FirstAgg other)
    {
        this.recs_buffer.Append(other.recs_buffer);
    }

    // Called at the end of aggregation, to return the results of the aggregation.
    public SqlString Terminate()
    {
        string output = string.Empty;
        //delete the trailing comma, if any
        if (this.recs_buffer != null
            && this.recs_buffer.Length > 0)
        {
            output = this.recs_buffer.ToString().Split(',')[0];
        }
        else
            output = null;


        return new SqlString(output);
    }

    public void Read(BinaryReader r)
    {
        recs_buffer = new StringBuilder(r.ReadString());
    }

    public void Write(BinaryWriter w)
    {
        w.Write(this.recs_buffer.ToString());
    }
}
